package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.canstants.SystemCanstants;
import org.example.domain.dto.CategoryDto;
import org.example.domain.entity.Article;
import org.example.domain.entity.Category;
import org.example.domain.result.ResponseResult;
import org.example.domain.vo.CategoryVo;
import org.example.domain.vo.PageVo;
import org.example.enmus.AppHttpCodeEnum;
import org.example.mapper.CategoryMapper;
import org.example.service.ArticleService;
import org.example.service.CategoryService;
import org.example.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.example.canstants.SystemCanstants.ARTICLE_STATUS_NORMAL;
import static org.example.canstants.SystemCanstants.STATUS_NORMAL;

/**
 * 分类表(Category)表服务实现类
 *
 * @author makejava
 * @since 2025-01-29 21:18:49
 */
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ArticleService articleService;


    //----------------------------写博客-查询文章分类的接口--------------------------------------
    @Override
    public List<CategoryVo> listAllCategory() {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getStatus, STATUS_NORMAL);
        List<Category> list = list(queryWrapper);
        List<CategoryVo> categoryVo = BeanCopyUtils.copyBeanList(list, CategoryVo.class);
        return categoryVo;
    }
    //----------------------------------分页查询分类列表------------------------------------------
    @Override
    public PageVo selectCategoryPage(Category category, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(category.getName()),Category::getName,category.getName());
        queryWrapper.eq(Objects.nonNull(category.getStatus()),Category::getStatus, category.getStatus());
        Page<Category> page = new Page<>();
        page.setCurrent(pageNum);
        page.setSize(pageSize);
        page(page,queryWrapper);
        //转换成VO
        List<Category> categories = page.getRecords();

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
        return pageVo;
    }

    @Override
    public ResponseResult getCategoryList() {
        //查询文章表，状态为已发布的文章
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus,ARTICLE_STATUS_NORMAL);
        List<Article> articleList = articleService.list(queryWrapper);
        //获取文章的分类id,并且去重
        Set<Long> categoryIds = articleList.stream()
                .map(new Function<Article, Long>() {
                    @Override
                    public Long apply(Article article){
                        return article.getCategoryId();
                    }
                })
                //把文章的分类id转换成Set集合
                .collect(Collectors.toSet());
        if (categoryIds.isEmpty()) {
            return ResponseResult.okResult(Collections.emptyList());
        }
        //查询分类表
        List<Category> categories = listByIds(categoryIds);
        categories = categories.stream()
                .filter(category -> STATUS_NORMAL.equals(category.getStatus()))
                .collect(Collectors.toList());

        //封装成CategoryVo实体类后返回给前端，CateGoryVo的作用只返回前端需要的字段。
        List<CategoryVo> categoryVos = BeanCopyUtils.copyBeanList(categories, CategoryVo.class);

        return ResponseResult.okResult(categoryVos);
    }

    @Override
    public ResponseResult add(CategoryDto categoryDto) {
        // 1. 校验分类名是否为空
        if (categoryDto.getName() == null || categoryDto.getName().isEmpty()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CATEGORY_NOT_NULL);
        }
        if (categoryDto.getName().length() > 20) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_TOO_LONG);
        }
        // 2. 校验分类名是否已存在
        Category existingCategory = categoryMapper.selectOne(new LambdaQueryWrapper<Category>()
                .eq(Category::getName, categoryDto.getName()));
        if (existingCategory != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CATEGORY_EXIST);
        }
        Category category = BeanCopyUtils.copyBean(categoryDto, Category.class);
        categoryMapper.insert(category);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult edit(Category category) {
        // 1. 校验分类名是否为空
        if (category.getName() == null || category.getName().isEmpty()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CATEGORY_NOT_NULL);
        }
        if (category.getName().length() > 20) {
            return ResponseResult.errorResult(AppHttpCodeEnum.CONTENT_TOO_LONG);
        }
        // 2. 获取当前分类id
        Category originalCategory = getById(category.getId());
        // 3. 只有当分类名称变化时才检测重名
        if (!originalCategory.getName().equals(category.getName())) {
            boolean nameExists = lambdaQuery()
                    .eq(Category::getName, category.getName().trim()) // 忽略前后空格
                    .ne(Category::getId, category.getId()) // 排除当前分类自身
                    .exists();
            if (nameExists) {
                return ResponseResult.errorResult(AppHttpCodeEnum.CATEGORY_EXIST);
            }
        }
        categoryMapper.updateById(category);
        return ResponseResult.okResult();
    }
}
